package com.summer.data.connection.sessioninterface;

import com.summer.data.Jsql;
import com.summer.data.connection.PageInfoHolder;
import com.summer.data.dialect.Dialect;
import com.summer.data.rs.Extractor;
import com.summer.data.rs.datatype.MapPage;
import com.summer.data.rs.datatype.ObjectPage;
import com.summer.data.rs.datatype.PageInfo;
import com.summer.data.rs.extractor.KeysExtractor;
import com.summer.data.rs.extractor.ManyRecordExtractor;
import com.summer.data.rs.extractor.OneRecordExtractor;

import java.util.List;
import java.util.Map;

/**
 * 基于 Jsql 的操作接口
 * @author 345480567@qq.com
 */
public interface JsqlSessionInterface extends BaseSessionInterface {

    default List<Map<String, Object>> query(Jsql jsql) {
        ManyRecordExtractor<Map<String, Object>> extractor = ManyRecordExtractor.createMapExtractor();
        return query(jsql, extractor);
    }

    default <T> List<T> query(Jsql jsql, Class<T> clazz) {
        ManyRecordExtractor<T> extractor = ManyRecordExtractor.createObjectExtractor(clazz);
        return query(jsql, extractor);
    }

    default Map<String, Object> first(Jsql jsql) {
        OneRecordExtractor<Map<String, Object>> extractor = OneRecordExtractor.createMapExtractor(false);
        return query(jsql, extractor);
    }

    default <T> T first(Jsql jsql, Class<T> clazz) {
        OneRecordExtractor<T> extractor = OneRecordExtractor.createObjectExtractor(clazz, false);
        return query(jsql, extractor);
    }

    default Map<String, Object> find(Jsql jsql) {
        OneRecordExtractor<Map<String, Object>> extractor = OneRecordExtractor.createMapExtractor(true);
        return query(jsql, extractor);
    }

    default <T> T find(Jsql jsql, Class<T> clazz) {
        OneRecordExtractor<T> extractor = OneRecordExtractor.createObjectExtractor(clazz, true);
        return query(jsql, extractor);
    }

    <T> T query(Jsql jsql, Extractor<T> extractor);

    default Integer executeUpdate(Jsql jsql) {
        return executeUpdate(jsql, null);
    }

    Integer executeUpdate(Jsql jsql, KeysExtractor keysExtractor);

    default Integer count(Jsql jsql) {
        Dialect dialect = getDialect();
        Jsql countJsql = dialect.getCountSql(jsql);
        Extractor<Integer> countExtracotr = dialect.getCountExtracter();
        return query(countJsql, countExtracotr);
    }

    default MapPage pageQuery(Jsql jsql) {
        Dialect dialect = getDialect();
        Integer cnt = count(jsql);

        PageInfo pageInfo = jsql.getPageInfo();

        // 获取 分页信息
        if (pageInfo == null) {
            pageInfo = PageInfoHolder.getPageInfo();
            if (pageInfo == null) {
                pageInfo = new PageInfo(1, 10);
            }
        }

        Jsql pageJsql = dialect.getPageSql(jsql, pageInfo);
        List<Map<String, Object>> mapList = query(pageJsql);

        return new MapPage(mapList, pageInfo, cnt);
    }

    default <T> ObjectPage<T> pageQuery(Jsql jsql, Class<T> clazz) {
        Dialect dialect = getDialect();
        Integer cnt = count(jsql);

        PageInfo pageInfo = jsql.getPageInfo();

        // 获取 分页信息
        if (pageInfo == null) {
            pageInfo = PageInfoHolder.getPageInfo();
            if (pageInfo == null) {
                pageInfo = new PageInfo(1, 10);
            }
        }

        Jsql pageJsql = dialect.getPageSql(jsql, pageInfo);
        List<T> list = query(pageJsql, clazz);

        return new ObjectPage<T>(list, pageInfo, cnt);
    }

}
